#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion

namespace Weazel.Gezel.Model
{
  /// <summary>
  /// A register stores a value which can be read and written
  /// during a clockcycle. The new value, however, is first
  /// visible in the next clock cycle.
  /// </summary>
  public partial class Register : AbstractEntity<Datapath>, ITypedEntity, ISignalEntity
  {
    /// <summary>
    /// The bitwidth of the register.
    /// </summary>
    private int width;
    public int Width
    {
      get { return width; }
			protected set { width = value; }
    }

    /// <summary>
    /// True iff the register is read as a
    /// two's complement integer.
    /// </summary>
    private bool signed;
    public bool Signed
    {
      get { return signed; }
			protected set { signed = value; }
    }

    /// <summary>
    /// The list of expressions which can drive
    /// this entity during simulation. The
    /// list is not populated before the
    /// verification has completed.
    /// </summary>
    private List<Expression> definers;
    public List<Expression> Definers
    {
      get
      {
        return definers;
      }
    }

    /// <summary>
    /// Maps each definer of this entity to the signalflowgraph
    /// in which the definer is active.
    /// </summary>
    private Dictionary<Expression, SignalFlowGraph> definingSignalFlowGraphs;
    public Dictionary<Expression, SignalFlowGraph> DefiningSignalFlowGraphs
    {
      get
      {
        return definingSignalFlowGraphs;
      }
    }

		public Register(
			Datapath parent, 
			string name, 
			int bitwidth, 
			bool signed, 
			Position startPosition,
			Position endPosition
		)
      : this(parent, name, bitwidth, signed)
    {
			this.startPosition = startPosition;
			this.endPosition = endPosition;
    }

    /// <summary>
    /// Constructs a new register with the specified datapath 
    /// as a parent.
    /// </summary>
    /// <param name="parent">the parent datapath</param>
    /// <param name="name">local register name</param>
    /// <param name="bitwidth">bitwith of the register</param>
    /// <param name="signed">is the register value signed</param>
    public Register(Datapath parent, string name, int bitwidth, bool signed) 
			: base(parent, name)
    {
      this.width = bitwidth;
      this.signed = signed;
			this.definers = new List<Expression>();
			this.definingSignalFlowGraphs = new Dictionary<Expression, SignalFlowGraph>();
    }

		protected Register(Datapath parent) 
			: base(parent, null) 
		{
			this.definers = new List<Expression>();
			this.definingSignalFlowGraphs = new Dictionary<Expression, SignalFlowGraph>();
		}

    public Register Clone(Datapath newParent)
    {
      return new Register(newParent, LocalName, Width, Signed, startPosition, endPosition);
    }
  }
}